﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sern.Abstracts.Common;
using Sern.Abstracts.Tracker.DataContracts;
using Sern.Abstracts.Tracker.ServiceContracts;
using Sern.Abstracts.Tracker.ServiceContracts.Fakes;
using Sern.Common;
using Sern.Common.Fakes;
using Sern.ServiceImplementation.MapReduce;
using Microsoft.Practices.Unity;

namespace Sern.Test.ServiceImplementation.MapReduce
{
    [TestClass]
    public class MapReduceClientAbstract_FailuresFailsBothParentAndNextKvp
    {        


        [TestInitialize]
        public void TestInitialize()
        {
            var jobId = Guid.NewGuid();

            ComponentLocator.Reset();

            ComponentLocator.Unity.RegisterInstance("EmissionLogs",new List<EmissionTrace>());
            var notices = ComponentLocator.Unity.Resolve<List<EmissionTrace>>("EmissionLogs");

            bool[] isSatisfied = new[] { false, true };
            int isSatisfiedIndex = 0;

            var mapReduce = new MapReduce<object, object>
                (
                    () => new StubIClient<ITrackerTelemetryReceiver>
                    {
                        ProxyGet = () => new StubITrackerTelemetryReceiver
                        {
                            NotifyProcessingNotice = notice => { }
                        }
                    },
                //TODO: Next one test if tracing is done correctly, then test if error logging is also done correctly.
                    () => new StubIClient<ITrackerLogging>
                    {
                        ProxyGet = () => new StubITrackerLogging
                        {
                            LogEmissionTrace = trace => notices.Add(trace),
                        }
                    },
                       (guid0, guid) => isSatisfied[isSatisfiedIndex++],
                       Guid.NewGuid(),
                       Guid.NewGuid(),
                       (key, value) => {throw new NotImplementedException("Expected exception needs to be handled and reported."); },
                       (key, value, action) => action("newKey", "newValue")
                );

            ComponentLocator.Unity.RegisterInstance<IMapReduce<object, object>>(mapReduce);
        }

        [TestMethod]
        public void TestNoticesAreFiredInOrder()
        {
            var mapReduceObject = ComponentLocator.Unity.Resolve<IMapReduce<object, object>>();
            mapReduceObject.Handle("startKey", "startValue");

            var emissionList = ComponentLocator.Unity.Resolve<List<EmissionTrace>>("EmissionLogs");
            
            //TODO: Change the thread sleep to a reset event.
            Thread.Sleep(50);

            Assert.IsTrue(emissionList.Any());

        }
    }
}
